## calculates matrices of differences in early voting hours across county borders

library(rgdal)
library(dplyr)
library(rgeos)
library(readr)
library(xtable)

## Read in county shape file
countyshp <- readOGR(dsn = "../shapes/CountyBoundary", layer = "CountyBoundary")
## Replace county name spaces with underscores in both county and precinct shapefiles
countyshp$NAME <- gsub(" ", "_", countyshp$NAME)

## Read in changes to early voting laws
polls <- read_delim(file = "2012-2016_Early_Voting_Changes.csv",
                    delim = "\t",
                    col_names = TRUE)
polls[is.na(polls)] <- 0
## change county to uppercase 
polls <- polls %>%  mutate(county = toupper(county))

## put "_" in county names that have spaces
polls$county <- gsub (" ", "_", polls$county)

## Merge in poll details into the shape file (using old merge command since left_join seems not to like shapefiles)
countyshp <- merge(x = countyshp, y = polls, by.x = "NAME", by.y = "county")

cols2save <-  c("county1", "county2",
                "border_length",

                "totalhoursChg1", "totalhoursChg2",
                "sitesChg1", "sitesChg2",
                "evehoursChg1", "evehoursChg2",
                "sathoursChg1", "sathoursChg2",
                "sunhoursChg1", "sunhoursChg2", 

                "totalhoursDID",
                "sitesDID",
                "evehoursDID",
                "sathoursDID",
                "sunhoursDID"
                )

results <- data.frame(matrix(nrow = 0, ncol = length(cols2save)), stringsAsFactors = FALSE)

## Step through each county and calculate intersections
for (county2use in 1:nrow(countyshp)) {
  
  cat (county2use)
  
  ## Determine the border counties for county i; touches is a vector of Booleans that
  ## describes if county county2use touches any other counties in NC
  touches <- gTouches(countyshp[county2use,], countyshp, byid = TRUE)
  
  ## For each county that is touched, compute length of border
  for (touch2use in 1:(sum(touches))) {
    touched <- grep("TRUE", touches)[touch2use]
    border = gDifference(as(countyshp[county2use,], "SpatialLines"),
                         as(gUnaryUnion(countyshp[c(county2use, touched),]), "SpatialLines"), 
                         byid = TRUE)
    if (!is.null(border)) {
      ## Do not save results for this border only if it does not exist
      if (!length(which(countyshp$NAME[county2use] == results[, match("county2", cols2save)] &
                        countyshp$NAME[touched] == results[, match("county1", cols2save)]))) {
          results[nrow(results) + 1,] <-
              ## Careful!!! Make sure the order of insertions below
              ## matches the variable order in cols2save!
              c(as.character(countyshp$NAME[county2use]), as.character(countyshp$NAME[touched]), 
                gLength(border),

                countyshp$totalhoursChg[county2use], countyshp$totalhoursChg[touched],
                countyshp$sitesChg[county2use], countyshp$sitesChg[touched],
                countyshp$evehoursChg[county2use], countyshp$evehoursChg[touched],
                countyshp$sathoursChg[county2use], countyshp$sathoursChg[touched],
                countyshp$sunhoursChg[county2use], countyshp$sunhoursChg[touched],
                
                abs(countyshp$totalhoursChg[county2use] - countyshp$totalhoursChg[touched]),
                abs(countyshp$sitesChg[county2use] - countyshp$sitesChg[touched]),
                abs(countyshp$evehoursChg[county2use] - countyshp$evehoursChg[touched]),
                abs(countyshp$sathoursChg[county2use] - countyshp$sathoursChg[touched]),
                abs(countyshp$sunhoursChg[county2use] - countyshp$sunhoursChg[touched]))
      }
    }
  }
}
colnames(results) <- cols2save

## Adjust county1 and county2 so that county1 also precedes county2 alphabetically
rows2flip <- which((results$county1 > results$county2) == TRUE)
for (row2flip in rows2flip) {
  ## flip county names
  temp <- results$county1[row2flip]     
  results$county1[row2flip] <- results$county2[row2flip]    
  results$county2[row2flip] <- temp
  ## flip percentage hour changes
  temp <- results$percentagehoursChg1[row2flip]     
  results$percentagehoursChg1[row2flip] <- results$percentagehoursChg2[row2flip]    
  results$percentagehoursChg2[row2flip] <- temp
  ## flip percentagesite site changes
  temp <- results$sitesChg1[row2flip]     
  results$sitesChg1[row2flip] <- results$sitesChg2[row2flip]    
  results$sitesChg2[row2flip] <- temp
  ## flip percentage eve hour changes
  temp <- results$evehoursChg1[row2flip]     
  results$evehoursChg1[row2flip] <- results$evehoursChg2[row2flip]    
  results$evehoursChg1[row2flip] <- temp
  ## flip percentage sat hour changes
  temp <- results$sathoursChg1[row2flip]     
  results$sathoursChg1[row2flip] <- results$sathoursChg2[row2flip]    
  results$sathoursChg2[row2flip] <- temp
  ## flip percentage sun hour changes
  temp <- results$sunhoursChg1[row2flip]     
  results$sunhoursChg1[row2flip] <- results$sunhoursChg2[row2flip]    
  results$sunhoursChg2[row2flip] <- temp
}

## save results
write_delim(results, 
            path = "county-early-voting-differences.csv", 
            delim = "\t", 
            col_names = TRUE)

## fix county capitalization in preparation for latex table code
capwords <- function(s, strict = FALSE) {
  cap <- function(s) paste(toupper(substring(s, 1, 1)),
                           {s <- substring(s, 2); if(strict) tolower(s) else s},
                           sep = "", collapse = " " )
  sapply(strsplit(s, split = " "), cap, USE.NAMES = !is.null(names(s)))
}

results$county1 <- capwords(tolower(results$county1))
results$county2 <- capwords(tolower(results$county2))

## Make some tex tables

for (col2use in grep("DID$", cols2save)) {

    name2use <- gsub("DID$", "", cols2save[col2use])
    results <- results[order(as.double(results[, col2use]), decreasing = TRUE),]
    col2usecounty1 <- match(paste(name2use, "Chg1", sep = ""), names(results))
    col2usecounty2 <- match(paste(name2use, "Chg2", sep = ""), names(results))
    col2useDID <- match (paste(name2use, "DID", sep = ""), names(results))
    colname2use <- paste(name2use, "DID", sep = "")
    file2use <- paste("borders_top20_", name2use, "DID.tex", sep = "")
    label2use <- paste("tab:county20", name2use, "DID", sep = "")
    if (name2use == "totalhours") {
        caption2use <- "Top 20 county borders based on percentage changes to EIP voting hours"
        nicename2use <- "Hours"
    }
    else if (name2use == "sites") {
        caption2use <- "Top 20 county borders based on percentage changes to EIP voting sites"
        nicename2use <- "EIP sites"
    }
    else if (name2use == "evehours") {
        caption2use <- "Top 20 county borders based on percentage changes to evening EIP voting hours"
        nicename2use <- "Evening hours"
    }
    else if (name2use == "sathours") {
        caption2use <- "Top 20 county borders based on percentage changes to Saturday EIP voting hours"
        nicename2use <- "Saturday hours"
    }
    else if (name2use == "sunhours") {
        caption2use <- "Top 20 county borders based on percentage changes to Sunurday EIP voting hours"
        nicename2use <- "Sunday hours"
    }
    else {
        stop ("Problem!  Cannot determine caption for table.\n")
    }
    
    ## save tex code
    
    xt <- xtable(x = head(results, 20)[,c(match("county1", names(results)),
                                          match("county2", names(results)),
                                          col2usecounty1,
                                          col2usecounty2,
                                          col2useDID)],
                 caption.placement = "top",
                 align = "lllccc",
                 type="latex",
                 caption = caption2use,
                 label = label2use)
    
    names(xt) <- c("County 1", "County 2", 
                   paste (nicename2use, ", County 1", sep = ""), paste (nicename2use, ", County 2", sep = ""),
                   "Difference")
    
    print (xt, 
           file = paste("../tex/", file2use, sep = ""),
           include.rownames = FALSE)
    
}


